/**
 * 
 */
package neptune.web.client.utils;

import neptune.web.client.model.topology.SerializableLink;
import neptune.web.client.model.topology.SerializableNode;
import neptune.web.client.model.topology.SerializableTopology;

/**
 * @author Roberto Bifulco [info@RobertoBifulco.it] [RobertoBifulco.it]
 * 
 */
public class TopologyGenerationUtils {

	private static final String NODE_NAME = "node";
	private static final String LINK_NAME = "link";
	private static String interfaceName = "eth";
	private static String[] hexCyphers = new String[] { "0", "1", "2", "3",
			"4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" };
	private static String[] hexSecondByteAllowedCyphers = new String[] { "2",
			"6", "A", "E" };

	/**
	 * Genera un MAC address casuale, senza verificarne l'unicita'.
	 * 
	 * @return
	 */
	public static String generateRandomMAC() {

		String[] address = new String[12];
		double[] indexes = new double[hexCyphers.length];
		for (int j = 0; j < indexes.length; j++)
			indexes[j] = (double) j / indexes.length;

		for (int i = 0; i < address.length; i++) {
			double rand = Math.random();

			int index = 0;
			while (index < hexCyphers.length - 1 && rand > indexes[index])
				index++;

			address[i] = hexCyphers[index];
		}

		double rand = Math.random();
		indexes = new double[hexSecondByteAllowedCyphers.length];
		for (int j = 0; j < indexes.length; j++)
			indexes[j] = j / indexes.length;

		int index = 0;
		while (index < hexSecondByteAllowedCyphers.length - 1
				&& rand > indexes[index])
			index++;
		address[1] = hexSecondByteAllowedCyphers[index];

		String composedAddress = "";
		for (int i = 0; i < address.length; i++) {
			composedAddress += address[i];
			if (i % 2 != 0 && i != address.length - 1)
				composedAddress += ":";
		}
		return composedAddress;
	}

	public static String generateNodeName(SerializableTopology topology) {

		boolean exists = false;
		int number = -1;
		String generated = NODE_NAME + number;

		do {
			exists = false;
			number++;
			generated = NODE_NAME + number;

			for (SerializableNode node : topology.getNodes()) {
				if (node.getId().equals(generated))
					exists = true;
			}
		} while (exists);

		return generated;
	}

	public static String generatelINKName(SerializableTopology topology) {

		boolean exists = false;
		int number = -1;
		String generated = LINK_NAME + number;

		do {
			exists = false;
			number++;
			generated = LINK_NAME + number;

			for (SerializableLink link : topology.getLinks()) {
				if (link.getId().equals(generated))
					exists = true;
			}
		} while (exists);

		return generated;
	}

	/**
	 * Definisce un nome di interfaccia univoco all'interno del nodo passato
	 * come argomento
	 * 
	 * @param node
	 * @return
	 */
	public static String defineNewInterfaceNameForNode(SerializableNode node) {
		int i = 1;
		boolean found = false;
		while (!found) {
			if (node.getInterfaceByName(interfaceName + i) == null)
				found = true;
			else
				i++;
		}

		return interfaceName + i;
	}
}
